package com.rede.didiok.community.restapi;


import java.util.*;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rede.didiok.common.annotion.log.BussinessLog;
import com.rede.didiok.common.constant.conf.MessageConf;
import com.rede.didiok.common.constant.conf.RedisConf;
import com.rede.didiok.common.constant.conf.SQLConf;
import com.rede.didiok.common.constant.conf.SysConf;
import com.rede.didiok.common.constant.conf.base.BaseSysConf;
import com.rede.didiok.common.constant.global.Constants;
import com.rede.didiok.common.domainEvent.EventAction;
import com.rede.didiok.common.dto.admin.WebConfigDto;
import com.rede.didiok.common.dto.community.MomentCommentDto;
import com.rede.didiok.common.dto.user.UserDto;
import com.rede.didiok.common.enums.*;
import com.rede.didiok.common.exception.ThrowableUtils;
import com.rede.didiok.common.exception.exceptionType.FeignException;
import com.rede.didiok.common.feign.AdminFeignClient;
import com.rede.didiok.common.feign.FileFeignClient;
import com.rede.didiok.common.feign.UserFeignClient;
import com.rede.didiok.common.holder.RequestHolder;
import com.rede.didiok.common.service.CommonService;
import com.rede.didiok.common.utils.*;
import com.rede.didiok.common.utils.business.*;
import com.rede.didiok.common.validator.group.Delete;
import com.rede.didiok.common.validator.group.GetList;
import com.rede.didiok.common.validator.group.GetOne;
import com.rede.didiok.common.validator.group.Insert;
import com.rede.didiok.community.entity.MomentCommentEntity;
import com.rede.didiok.community.entity.MomentCommentReportEntity;
import com.rede.didiok.community.entity.UserMomentEntity;
import com.rede.didiok.community.service.MomentCommentReportService;
import com.rede.didiok.community.service.MomentCommentService;
import com.rede.didiok.community.service.UserMomentService;

/**
 * 评论RestApi
 *
 * @author 陌溪
 * @date 2020年1月11日16:11:55
 */
@RestController
@RefreshScope
@RequestMapping("/momentComment")
@Api(value = "评论相关接口", tags = {"评论相关接口"})
@Slf4j
public class MomentCommentRestApi {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private WebUtil webUtil;
    @Autowired
    private UserUtil userUtil;
    @Autowired
    private AdminFeignClient adminFeignClient;
    @Autowired
    private RabbitMqUtil rabbitMqUtil;
    @Autowired
    private UserMomentService userMomentService;
    @Autowired
    private MomentCommentService momentCommentService;
    @Autowired
    private MomentCommentReportService momentCommentReportService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private UserFeignClient userFeignClient;
    @Resource
    private FileFeignClient fileFeignClient;
    @Autowired
    private SensitiveUtils sensitiveUtils;
    @Value(value = "${RANK.USER_TOKEN_SURVIVAL_TIME}")
    private Long userTokenSurvivalTime;
    @Value(value = "${data.website.url}")
    private String dataWebsiteUrl;
    @Resource
    private FileFeignUtil fileFeignUtil;
    /**
     * 领域事件工具类
     */
    @Resource
    private DomainEventUtil domainEventUtil;

    /**
     * 获取评论列表
     *
     * @param commentDto
     * @param result
     * @return
     */
    @ApiOperation(value = "获取评论列表", notes = "获取评论列表")
    @PostMapping("/getList")
    public String getList(@Validated({GetList.class}) @RequestBody MomentCommentDto commentDto, BindingResult result) {

        ThrowableUtils.checkParamArgument(result);

        IPage<MomentCommentEntity> commentIPage = momentCommentService.getUserCommentList(commentDto);
        List<MomentCommentEntity> commentList = commentIPage.getRecords();

        List<MomentCommentEntity> firstComment = new ArrayList<>();
        commentList.forEach(item -> {
            if (StringUtils.isEmpty(item.getToUid())) {
                firstComment.add(item);
            }
        });
        // 设置一级评论下的子评论
        if (commentDto.isOpenSecondLevel()) {
            // 获取所有二级
            Map<String, List<MomentCommentEntity>> secondCommentMap = new HashMap<>();
            for (MomentCommentEntity comment: commentList) {
                if (StringUtils.isEmpty(comment.getToUid())) {
                    continue;
                }
                List<MomentCommentEntity> comments = secondCommentMap.get(comment.getFirstCommentUid());
                if (comments == null) {
                    comments = new ArrayList<>();
                }
                comments.add(comment);
                secondCommentMap.put(comment.getFirstCommentUid(), comments);
            }
            for (MomentCommentEntity comment: firstComment) {
                comment.setReplyList(secondCommentMap.get(comment.getUid()));
            }
            commentIPage.setRecords(firstComment);
        } else {
            Map<String, List<MomentCommentEntity>> toCommentListMap = new HashMap<>();
            for (int a = 0; a < commentList.size(); a++) {
                List<MomentCommentEntity> tempList = new ArrayList<>();
                for (int b = 0; b < commentList.size(); b++) {
                    if (commentList.get(a).getUid().equals(commentList.get(b).getToUid())) {
                        tempList.add(commentList.get(b));
                    }
                }
                toCommentListMap.put(commentList.get(a).getUid(), tempList);
            }

            commentIPage.setRecords(getCommentReplys(firstComment, toCommentListMap));
        }
        return ResultUtil.result(SysConf.SUCCESS, commentIPage);
    }

    @ApiOperation(value = "App端获取评论列表", notes = "获取评论列表")
    @PostMapping("/getListByApp")
    public String getListByApp(@Validated({GetList.class}) @RequestBody MomentCommentDto commentDto, BindingResult result) {

        ThrowableUtils.checkParamArgument(result);
        QueryWrapper<MomentCommentEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(commentDto.getMomentUid())) {
            queryWrapper.like(SQLConf.MEMBER_UID, commentDto.getMomentUid());
        }
        queryWrapper.eq(SQLConf.SOURCE, commentDto.getSource());
        //分页
        Page<MomentCommentEntity> page = new Page<>();
        page.setCurrent(commentDto.getCurrentPage());
        page.setSize(commentDto.getPageSize());
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        queryWrapper.eq(SQLConf.TYPE, CommentTypeEnum.COMMENT);
        // 查询出该文章下所有的评论
        IPage<MomentCommentEntity> pageList = momentCommentService.page(page, queryWrapper);
        List<MomentCommentEntity> list = pageList.getRecords();
        List<String> toCommentUidList = new ArrayList<>();
        // 判断回复评论的UID
        list.forEach(item -> {
            toCommentUidList.add(item.getToUid());
        });

        // 定义一个数组，用来存放全部的评论
        List<MomentCommentEntity> allCommentList = new ArrayList<>();
        allCommentList.addAll(list);

        // 查询出回复的评论
        Collection<MomentCommentEntity> toCommentList = null;
        if (toCommentUidList.size() > 0) {
            toCommentList = momentCommentService.listByIds(toCommentUidList);
            allCommentList.addAll(toCommentList);
        }

        // 查询出评论用户的基本信息
        List<String> userUidList = new ArrayList<>();
        allCommentList.forEach(item -> {
            String userUid = item.getCreateUserUid();
            String toUserUid = item.getToUserUid();
            if (StringUtils.isNotEmpty(userUid)) {
                userUidList.add(item.getCreateUserUid());
            }
            if (StringUtils.isNotEmpty(toUserUid)) {
                userUidList.add(item.getToUserUid());
            }
        });
        List<UserDto> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            R userResult = userFeignClient.listUserByUids(userUidList);
            if (userResult.getCode() == 0) {
                userList = userResult.getData(new TypeReference<List<UserDto>>(){});
            }else {
                throw new FeignException("feign调用异常（根据用户id列表找用户）：失败");
            }
        }

        // 过滤掉用户的敏感信息
        List<UserDto> filterUserList = new ArrayList<>();
        userList.forEach(item -> {
            UserDto user = new UserDto();
            user.setAvatar(item.getAvatar());
            user.setUid(item.getUid());
            user.setNickname(item.getNickname());
            user.setUserTag(item.getUserTag());
            filterUserList.add(user);
        });

        // 获取用户头像
        List<String> fileUidList = new ArrayList<>();
        filterUserList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getAvatar())) {
                fileUidList.add(item.getAvatar());
            }
        });
        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);

        Map<String, UserDto> userMap = new HashMap<>();
        filterUserList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getAvatar()) && pictureMap.get(item.getAvatar()) != null) {
                item.setPhotoUrl(pictureMap.get(item.getAvatar()));
            }
            userMap.put(item.getUid(), item);
        });

        // 定义一个评论Map键值对
        Map<String, MomentCommentEntity> commentMap = new HashMap<>();
        allCommentList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                item.setUser(userMap.get(item.getCreateUserUid()));
            }
            if (StringUtils.isNotEmpty(item.getToUserUid())) {
                item.setToUser(userMap.get(item.getToUserUid()));
            }
            commentMap.put(item.getUid(), item);
        });

        // 给查询出来的评论添加基本信息
        List<MomentCommentEntity> returnCommentList = new ArrayList<>();
        list.forEach(item -> {
            String commentUid = item.getUid();
            String toCommentUid = item.getToUid();
            MomentCommentEntity comment = commentMap.get(commentUid);
            if (StringUtils.isNotEmpty(toCommentUid)) {
                comment.setToComment(commentMap.get(toCommentUid));
            }
            returnCommentList.add(comment);
        });
        pageList.setRecords(returnCommentList);
        return ResultUtil.result(SysConf.SUCCESS, pageList);
    }

    @ApiOperation(value = "获取用户的评论列表", notes = "获取用户的评论列表")
    @PostMapping("/getCommentListByUser")
    public String getCommentListByUser(HttpServletRequest request, @Validated({GetList.class}) @RequestBody UserDto userDto) {

        String requestUserUid = request.getAttribute(SysConf.USER_UID).toString();
//        QueryWrapper<MomentCommentEntity> queryWrapper = new QueryWrapper<>();

        //分页
        Page<MomentCommentEntity> page = new Page<>();
        page.setCurrent(userDto.getCurrentPage());
        page.setSize(userDto.getPageSize());
//        queryWrapper.eq(SQLConf.TYPE, CommentTypeEnum.COMMENT);
//        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
//        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
//        // 查找出 我的评论
//        queryWrapper.and(wrapper -> wrapper.eq(SQLConf.CREATE_USER_UID, requestUserUid));
//        IPage<MomentCommentEntity> pageList = momentCommentService.page(page, queryWrapper);
        // 组装查询字段
        MomentCommentDto comment = new MomentCommentDto();
        comment.setCreateUserUid(requestUserUid);
        comment.setType(CommentTypeEnum.COMMENT);
        comment.setStatus(StatusEnum.ENABLE);
        comment.setOrderBy(SQLConf.CREATE_TIME + " desc");
        // 查找出 我的评论

        IPage<MomentCommentEntity> pageList = momentCommentService.queryPageWithMoment(page, comment);
        List<MomentCommentEntity> list = pageList.getRecords();
//        List<String> userUidList = new ArrayList<>();
//        list.forEach(item -> {
//            String userUid = item.getCreateUserUid();
//            if (StringUtils.isNotEmpty(userUid)) {
//                userUidList.add(item.getCreateUserUid());
//            }
//        });
//
//        // 获取用户列表
//        Collection<UserDto> userList = new ArrayList<>();
//        if (userUidList.size() > 0) {
//            R userResult = userFeignClient.listUserByUids(userUidList);
//            if (userResult.getCode() == 0) {
//                userList = userResult.getData(new TypeReference<List<UserDto>>(){});
//            }else {
//                throw new FeignException("feign调用异常（根据用户id列表找用户）：失败");
//            }
//        }
//        // 过滤掉用户的敏感信息
//        List<UserDto> filterUserList = new ArrayList<>();
//        userList.forEach(item -> {
//            UserDto user = new UserDto();
//            user.setAvatar(item.getAvatar());
//            user.setUid(item.getUid());
//            user.setNickname(item.getNickname());
//            filterUserList.add(user);
//        });
//        // 获取用户头像
//        StringBuffer fileUids = new StringBuffer();
//        filterUserList.forEach(item -> {
//            if (StringUtils.isNotEmpty(item.getAvatar())) {
//                fileUids.append(item.getAvatar() + SysConf.FILE_SEGMENTATION);
//            }
//        });
//        String pictureList = null;
//        if (fileUids != null) {
//            pictureList = fileFeignClient.getPicture(fileUids.toString(), SysConf.FILE_SEGMENTATION);
//        }
//        List<Map<String, Object>> picList = webUtil.getPictureMap(pictureList);
//        Map<String, String> pictureMap = new HashMap<>();
//        picList.forEach(item -> {
//            pictureMap.put(item.get(SQLConf.UID).toString(), item.get(SQLConf.URL).toString());
//        });
//
//        Map<String, UserDto> userMap = new HashMap<>();
//        filterUserList.forEach(item -> {
//            if (StringUtils.isNotEmpty(item.getAvatar()) && pictureMap.get(item.getAvatar()) != null) {
//                item.setPhotoUrl(pictureMap.get(item.getAvatar()));
//            }
//            userMap.put(item.getUid(), item);
//        });

        // 将评论列表划分为 我的评论 和 我的回复
//        List<MomentCommentEntity> commentList = new ArrayList<>();
        list.forEach(item -> {
//            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
//                item.setUser(userMap.get(item.getCreateUserUid()));
//            }
            // 设置sourceName
            if (StringUtils.isNotEmpty(item.getSource())) {
                try {
                    item.setSourceName(CommentSourceEnum.valueOf(item.getSource()).getName());
                } catch (Exception e) {
                    log.error("ECommentSource转换异常");
                }
            }
//            if (requestUserUid.equals(item.getCreateUserUid())) {
//                commentList.add(item);
//            }
        });

//        pageList.setRecords(commentList);
        return ResultUtil.result(SysConf.SUCCESS, pageList);
    }

    @ApiOperation(value = "获取用户的回复", notes = "获取用户的回复")
    @PostMapping("/getReplyListByUser")
    public String getReplyListByUser(HttpServletRequest request, @Validated({GetList.class}) @RequestBody UserDto userDto) {

        String requestUserUid = RequestHolder.getUserUid();
//        QueryWrapper<MomentCommentEntity> queryWrapper = new QueryWrapper<>();

        //分页
        Page<MomentCommentEntity> page = new Page<>();
        page.setCurrent(userDto.getCurrentPage());
        page.setSize(userDto.getPageSize());
//        queryWrapper.eq(SQLConf.TYPE, CommentTypeEnum.COMMENT);
//        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
//        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
//        // 查找出我的回复
//        queryWrapper.and(wrapper -> wrapper.eq(SQLConf.TO_USER_UID, requestUserUid));
//        IPage<MomentCommentEntity> pageList = momentCommentService.page(page, queryWrapper);
        MomentCommentDto comment = new MomentCommentDto();
        comment.setToUserUid(requestUserUid);
        comment.setType(CommentTypeEnum.COMMENT);
        comment.setStatus(StatusEnum.ENABLE);
        comment.setOrderBy(SQLConf.CREATE_TIME + " desc");
        // 查找出 回复我的
        IPage<MomentCommentEntity> pageList = momentCommentService.queryPageWithMoment(page, comment);

        List<MomentCommentEntity> list = pageList.getRecords();
        List<String> userUidList = new ArrayList<>();
        list.forEach(item -> {
            String userUid = item.getCreateUserUid();
            if (StringUtils.isNotEmpty(userUid)) {
                userUidList.add(userUid);
            }
        });

        // 获取用户列表
        Collection<UserDto> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            R userResult = userFeignClient.listUserByUids(userUidList);
            if (userResult.getCode() == 0) {
                userList = userResult.getData(new TypeReference<List<UserDto>>(){});
            }else {
                throw new FeignException("feign调用异常（根据用户id列表找用户）：失败");
            }
        }

        //设置用户头像
        userUtil.setUserAvatar(userList);
        // 过滤用户敏感信息
        userUtil.convertUserList(userList);

        Map<String, UserDto> userMap = new HashMap<>();
        userList.forEach(item -> {
            userMap.put(item.getUid(), item);
        });

//        List<MomentCommentEntity> commentList = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                item.setUser(userMap.get(item.getCreateUserUid()));
            }
            // 设置sourceName
            if (StringUtils.isNotEmpty(item.getSource())) {
                try {
                    item.setSourceName(CommentSourceEnum.valueOf(item.getSource()).getName());
                } catch (Exception e) {
                    log.error("ECommentSource转换异常");
                }
            }
//            if (requestUserUid.equals(item.getToUserUid())) {
//                commentList.add(item);
//            }
        });

//        pageList.setRecords(commentList);
        return ResultUtil.result(SysConf.SUCCESS, pageList);
    }

    /**
     * 获取用户点赞信息
     *
     * @return
     */
    @ApiOperation(value = "获取用户点赞信息", notes = "增加评论")
    @PostMapping("/getPraiseListByUser")
    public String getPraiseListByUser(@ApiParam(name = "currentPage", value = "当前页数", required = false) @RequestParam(name = "currentPage", required = false, defaultValue = "1") Long currentPage,
                                      @ApiParam(name = "pageSize", value = "每页显示数目", required = false) @RequestParam(name = "pageSize", required = false, defaultValue = "10") Long pageSize) {

        String userUid = RequestHolder.getUserUid();
        QueryWrapper<MomentCommentEntity> queryWrappe = new QueryWrapper<>();
        queryWrappe.eq(SQLConf.CREATE_USER_UID, userUid);
        queryWrappe.eq(SQLConf.TYPE, CommentTypeEnum.PRAISE);
        queryWrappe.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrappe.orderByDesc(SQLConf.CREATE_TIME);
        Page<MomentCommentEntity> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(pageSize);
        IPage<MomentCommentEntity> pageList = momentCommentService.page(page, queryWrappe);
        List<MomentCommentEntity> praiseList = pageList.getRecords();
        List<String> momentUids = new ArrayList<>();
        praiseList.forEach(item -> {
            momentUids.add(item.getMomentUid());
        });
        Map<String, UserMomentEntity> momentMap = new HashMap<>();
        if (momentUids.size() > 0) {
            Collection<UserMomentEntity> blogList = userMomentService.listByIds(momentUids);
            blogList.forEach(blog -> {
                // 并不需要content内容
                blog.setContent("");
                momentMap.put(blog.getUid(), blog);
            });
        }

        praiseList.forEach(item -> {
            if (momentMap.get(item.getMomentUid()) != null) {
                item.setUserMoment(momentMap.get(item.getMomentUid()));
            }
        });
        pageList.setRecords(praiseList);
        return ResultUtil.result(SysConf.SUCCESS, pageList);
    }

    @BussinessLog(value = "发表评论", behavior = BehaviorEnum.PUBLISH_MOMENT_COMMENT)
    @ApiOperation(value = "增加评论", notes = "增加评论")
    @PostMapping("/add")
    public String add(@Validated({Insert.class}) @RequestBody MomentCommentDto commentDto, BindingResult result) {
        ThrowableUtils.checkParamArgument(result);
        R configResult = adminFeignClient.getWebConfig();
        WebConfigDto webConfig = null;
        if (configResult.getCode() == 0) {
            webConfig = configResult.getData(new TypeReference<WebConfigDto>(){});
        }else {
            throw new FeignException("feign调用异常（获取网站配置）：失败");
        }
        // 判断是否开启全局评论功能
        if (SysConf.CAN_NOT_COMMENT.equals(webConfig.getOpenComment())) {
            return ResultUtil.errorWithMessage(MessageConf.NO_COMMENTS_OPEN);
        }

        // 判断该博客是否开启评论功能
        if (StringUtils.isNotEmpty(commentDto.getMomentUid())) {
            UserMomentEntity rankMoment = userMomentService.getById(commentDto.getMomentUid());
            if (SysConf.CAN_NOT_COMMENT.equals(rankMoment.getOpenComment())) {
                return ResultUtil.errorWithMessage(MessageConf.RANK_MEMBER_NO_OPEN_COMMENTS);
            }
        }

        String userUid = RequestHolder.getUserUid();
        R userResult = userFeignClient.getUserById(userUid);
        UserDto user;
        if(userResult.getCode()==0){
            user = userResult.getData(new TypeReference<UserDto>(){});
        }else {
            // 获取异常信息
            throw new FeignException("feign调用异常（根据用户id找用户）：失败");
        }

        // 判断该用户是否被禁言
        if (user.getCommentStatus() == SysConf.ZERO) {
            return ResultUtil.errorWithMessage(MessageConf.YOU_DONT_HAVE_PERMISSION_TO_SPEAK);
        }
        // 判断是否发送过多无意义评论
        String jsonResult = redisUtil.get(RedisConf.USER_PUBLISH_SPAM_COMMENT_COUNT + BaseSysConf.REDIS_SEGMENTATION + userUid);
        if (!StringUtils.isEmpty(jsonResult)) {
            Integer count = Integer.valueOf(jsonResult);
            if (count >= Constants.NUM_FIVE) {
                return ResultUtil.errorWithMessage(MessageConf.PLEASE_TRY_AGAIN_IN_AN_HOUR);
            }
        }
        // 判断是否垃圾评论
        String content = commentDto.getContent();
        Map<String, String> sensitiveMap = sensitiveUtils.filter(content,false, SysConf.SYS_SENSITIVE_WORD);
        if (Integer.parseInt(sensitiveMap.get(SysConf.COUNT)) > Constants.NUM_ZERO) {
            if (StringUtils.isEmpty(jsonResult)) {
                Integer count = 0;
                redisUtil.setEx(RedisConf.USER_PUBLISH_SPAM_COMMENT_COUNT + BaseSysConf.REDIS_SEGMENTATION + userUid, count.toString(), 1, TimeUnit.HOURS);
            } else {
                redisUtil.incrBy(RedisConf.USER_PUBLISH_SPAM_COMMENT_COUNT + BaseSysConf.REDIS_SEGMENTATION + userUid, 1);
            }
            commentDto.setContent(sensitiveMap.get(SysConf.CONTENT));
        }

        MomentCommentEntity comment = new MomentCommentEntity();
        comment.setSource(commentDto.getSource());
        comment.setMomentUid(commentDto.getMomentUid());
        String blogContent = "";
        if (SensitiveUtils.REPLACEMENT.equals(commentDto.getContent())) {
            blogContent = commentDto.getContent();
        } else {
            // 将Markdown转换成html
            blogContent = FileUtils.markdownToHtml(commentDto.getContent());
        }
        comment.setContent(blogContent);


        // 当该评论不是一级评论时，需要设置一级评论UID字段
        if (StringUtils.isNotEmpty(commentDto.getToUid())) {
            MomentCommentEntity toComment = momentCommentService.getById(commentDto.getToUid());
            assert toComment != null;
            // 表示 toComment 是非一级评论
            if (StringUtils.isNotEmpty(toComment.getFirstCommentUid())) {
                comment.setFirstCommentUid(toComment.getFirstCommentUid());
            } else {
                // 表示父评论是一级评论，直接获取UID
                comment.setFirstCommentUid(toComment.getUid());
            }

            comment.setToUserUid(commentDto.getToUserUid());
        }

        // 判断评论是否需要审核
        Integer auditType = commonService.checkIsAudit(RequestHolder.getRequest(), comment.getContent());
        if (auditType.equals(AuditStatusEnum.AGREE)){
            comment.setAuditName("系统");
            comment.setAuditTime(new Date());
            comment.setAuditStatus(Integer.valueOf(AuditStatusEnum.AGREE));
        }else {
            comment.setAuditStatus(Integer.valueOf(AuditStatusEnum.WAIT));
        }

        comment.setCreateUserUid(userUid);
        comment.setToUid(commentDto.getToUid());
        comment.setStatus(StatusEnum.ENABLE);
        comment.insert();

        //获取用户头像
        if (StringUtils.isNotEmpty(user.getAvatar())) {
            String pictureList = fileFeignClient.getPicture(user.getAvatar(), SysConf.FILE_SEGMENTATION);
            if (webUtil.getPicture(pictureList).size() > 0) {
                user.setPhotoUrl(webUtil.getPicture(pictureList).get(0));
            }
        }
        comment.setUser(user);

        // 发送评论新增事件
        MomentCommentDto dto = new MomentCommentDto();
        BeanUtils.copyProperties(comment, dto);
        domainEventUtil.publishEvent(EventAction.MOMENT_COMMENT_ADD, dto);
        return ResultUtil.result(SysConf.SUCCESS, comment);
    }

    @BussinessLog(value = "举报评论", behavior = BehaviorEnum.REPORT_MEMBER_COMMENT)
    @ApiOperation(value = "举报评论", notes = "举报评论")
    @PostMapping("/report")
    public String reportComment(@Validated({GetOne.class}) @RequestBody MomentCommentDto commentDto, BindingResult result) {

        ThrowableUtils.checkParamArgument(result);
        MomentCommentEntity comment = momentCommentService.getById(commentDto.getUid());
        // 判断评论是否被删除
        if (comment == null || comment.getStatus() == StatusEnum.DISABLED) {
            return ResultUtil.errorWithMessage(MessageConf.COMMENT_IS_NOT_EXIST);
        }

        // 判断举报的评论是否是自己的
        if (comment.getCreateUserUid().equals(commentDto.getCreateUserUid())) {
            return ResultUtil.errorWithMessage(MessageConf.CAN_NOT_REPORT_YOURSELF_COMMENTS);
        }
        // 查看该用户是否重复举报该评论
        QueryWrapper<MomentCommentReportEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.CREATE_USER_UID, commentDto.getCreateUserUid());
        queryWrapper.eq(SQLConf.REPORT_COMMENT_UID, comment.getUid());
        List<MomentCommentReportEntity> commentReportList = momentCommentReportService.list(queryWrapper);
        if (commentReportList.size() > 0) {
            return ResultUtil.errorWithMessage(MessageConf.CAN_NOT_REPEAT_REPORT_COMMENT);
        }
        MomentCommentReportEntity commentReport = new MomentCommentReportEntity();
        commentReport.setContent(commentDto.getContent());
        commentReport.setProgress(0);
        // 从VO中获取举报的用户uid
        commentReport.setCreateUserUid(commentDto.getCreateUserUid());
        commentReport.setReportCommentUid(comment.getUid());
        // 从entity中获取被举报的用户uid
        commentReport.setReportUserUid(comment.getCreateUserUid());
        commentReport.setStatus(StatusEnum.ENABLE);
        commentReport.insert();

        return ResultUtil.result(SysConf.SUCCESS, MessageConf.OPERATION_SUCCESS);
    }

    /**
     * 通过UID删除评论
     *
     * @param commentDto
     * @param result
     * @return
     */
    @BussinessLog(value = "删除评论", behavior = BehaviorEnum.DELETE_MOMENT_COMMENT)
    @ApiOperation(value = "删除评论", notes = "删除评论")
    @PostMapping("/delete")
    public String deleteBatch(@Validated({Delete.class}) @RequestBody MomentCommentDto commentDto, BindingResult result) {

        ThrowableUtils.checkParamArgument(result);
        String userUid = RequestHolder.getUserUid();
        MomentCommentEntity comment = momentCommentService.getById(commentDto.getUid());
        // 判断该评论是否能够删除
        if (!comment.getCreateUserUid().equals(userUid)) {
            return ResultUtil.errorWithMessage(MessageConf.DATA_NO_PRIVILEGE);
        }
        comment.setStatus(StatusEnum.DISABLED);
        comment.updateById();

        // 获取该评论下的子评论进行删除
        // 传入需要被删除的评论 【因为这里是一条，我们需要用List包装一下，以后可以用于多评论的子评论删除】
        List<MomentCommentEntity> commentList = new ArrayList<>(Constants.NUM_ONE);
        commentList.add(comment);

        // 判断删除的是一级评论还是子评论
        String firstCommentUid = "";
        if (StringUtils.isNotEmpty(comment.getFirstCommentUid())) {
            // 删除的是子评论
            firstCommentUid = comment.getFirstCommentUid();
        } else {
            // 删除的是一级评论
            firstCommentUid = comment.getUid();

        }

        // 获取该评论一级评论下所有的子评论
        QueryWrapper<MomentCommentEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.FIRST_COMMENT_UID, firstCommentUid);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        List<MomentCommentEntity> toCommentList = momentCommentService.list(queryWrapper);
        List<MomentCommentEntity> resultList = new ArrayList<>();
        this.getToCommentList(comment, toCommentList, resultList);
        // 将所有的子评论也删除
        if (resultList.size() > 0) {
            resultList.forEach(item -> {
                item.setStatus(StatusEnum.DISABLED);
                item.setUpdateTime(new Date());
            });
            momentCommentService.updateBatchById(resultList);
        }

        // 发送评论新增事件
        MomentCommentDto dto = new MomentCommentDto();
        BeanUtils.copyProperties(comment, dto);
        domainEventUtil.publishEvent(EventAction.MOMENT_COMMENT_DELETE, dto);

        return ResultUtil.result(SysConf.SUCCESS, MessageConf.DELETE_SUCCESS);
    }

    @ApiOperation(value = "关闭评论邮件通知", notes = "关闭评论邮件通知")
    @GetMapping("/closeEmailNotification/{userUid}")
    public String bindUserEmail(@PathVariable("userUid") String userUid) {

        R updateResult = userFeignClient.closeEmailNotificationById(userUid);
        UserDto user;
        if(updateResult.getCode()==0){
            user = updateResult.getData(new TypeReference<UserDto>(){});
        }else {
            // 获取异常信息
            throw new FeignException("feign调用异常（关闭邮件通知）：失败");
        }


        // 通过user中获取的token，去修改redis中的信息
        if (StringUtils.isNotEmpty(user.getValidCode())) {
            String accessToken = user.getValidCode();
            String userInfo = redisUtil.get(RedisConf.USER_TOKEN + Constants.SYMBOL_COLON + accessToken);
            if (StringUtils.isNotEmpty(userInfo)) {
                Map<String, Object> map = JsonUtils.jsonToMap(userInfo);
                // 关闭邮件通知
                map.put(SysConf.START_EMAIL_NOTIFICATION, 0);
                redisUtil.setEx(RedisConf.USER_TOKEN + Constants.SYMBOL_COLON + accessToken, JsonUtils.objectToJson(map), userTokenSurvivalTime, TimeUnit.HOURS);
            }
        }

        return ResultUtil.result(SysConf.SUCCESS, MessageConf.OPERATION_SUCCESS);
    }


    /**
     * 获取评论所有回复
     *
     * @param list
     * @param toCommentListMap
     * @return
     */
    private List<MomentCommentEntity> getCommentReplys(List<MomentCommentEntity> list, Map<String, List<MomentCommentEntity>> toCommentListMap) {
        if (list == null || list.size() == 0) {
            return new ArrayList<>();
        } else {
            list.forEach(item -> {
                String commentUid = item.getUid();
                List<MomentCommentEntity> replyCommentList = toCommentListMap.get(commentUid);
                List<MomentCommentEntity> replyComments = getCommentReplys(replyCommentList, toCommentListMap);
                item.setReplyList(replyComments);
            });
            return list;
        }
    }

    /**
     * 获取二级评论列表
     * @param list
     * @param toCommentListMap
     * @return
     */
    private List<MomentCommentEntity> getCommentReplysLv2(List<MomentCommentEntity> list, Map<String, List<MomentCommentEntity>> toCommentListMap) {
        if (list == null || list.size() == 0) {
            return new ArrayList<>();
        }

        return null;
    }

    /**
     * 获取某条评论下的所有子评论
     *
     * @return
     */
    private void getToCommentList(MomentCommentEntity comment, List<MomentCommentEntity> commentList, List<MomentCommentEntity> resultList) {
        if (comment == null) {
            return;
        }
        String commentUid = comment.getUid();
        for (MomentCommentEntity item : commentList) {
            if (commentUid.equals(item.getToUid())) {
                resultList.add(item);
                // 寻找子评论的子评论
                getToCommentList(item, commentList, resultList);
            }
        }
    }
}

